// 登录接口
const connection = require("../../config/mysql.js");
const bcrypt = require("bcryptjs");
const jwtUtil = require("../utils/permission/jwtutil"); // 导入token模块
// 导入添加log
const { addUserLog } = require("../utils/permission/log.js")


const login = async (ctx) => {
    const { username, password } = ctx.request.body;
    // 查询数据库中是否存在该用户
    const sql = "select * from user where username = ?";
    const [result] = await connection.execute(sql, [username]);
    if (result.length === 0) {
        ctx.body = {
            code: 400,
            msg: "用户不存在",
            data: null,
        };
        return;
    }
    // 比较密码是否正确
    const isPasswordValid = bcrypt.compareSync(password, result[0].password);
    if (!isPasswordValid) {
        ctx.body = {
            code: 400,
            msg: "密码错误",
            data: null,
        };
        return;
    }
    // 记录最后登录时间
    const updateSql = "update user set lastLoginTime = ? where username = ?";
    await connection.execute(updateSql, [new Date(), username]);
    // 生成token
    const token = jwtUtil.encrypt(result[0]);
    // result[0]移除敏感信息后返还给用户
    const data = {
        id: result[0].id,
        username: result[0].username,
        nick: result[0].nick,
        type: result[0].type,
        permission: result[0].permission,
    }
    ctx.body = {
        code: 1,
        msg: "登录成功",
        data,
        token,
    }
}
// 注册接口
const register = async (ctx) => {
    try {
        
        const { username, password, nick, permission } = ctx.request.body;
        console.log(username, password, nick, permission);
        // 查询数据库中是否存在该用户
        const sql = "select * from user where username = ?";
        const [result] = await connection.execute(sql, [username]);
        if (result.length > 0) {
            ctx.body = {
                code: 400,
                msg: "用户已存在",
                data: null,
            };
            return;
        }
        // 密码加密
        const salt = bcrypt.genSaltSync(10);
        const hash = bcrypt.hashSync(password, salt);

        const currentTime = new Date().toISOString().slice(0, 19).replace("T", " ");

        console.log(hash);
        const permissionData = JSON.stringify(permission);
        // 插入数据库
        const insertSql = "insert into user (username, password, nick, permission,type,creationTime) values (?, ?, ?, ?,1,?)";
        await connection.execute(insertSql, [username, hash, nick, permissionData,currentTime]);
        ctx.body = {
            code: 1,
            msg: "添加账号成功",
            data: null,
        }
    }
    catch (error) {
        ctx.body = {
            code: 500,
            msg: "服务器错误",
            data: null,
        }
    }
}
// 获取用户列表
const getUserList = async (ctx) => {
    try {
        const [rows] = await connection.query('SELECT * FROM user');
        ctx.status = 200;
        ctx.body = {
            code: 1,
            msg: '获取成功',
            data: rows,
        }
    } catch {
        ctx.status = 500;
        ctx.body = {
            code: 500,
            msg: '服务器错误',
            data: null,
        }
    }
}
// 修改用户信息
const updateUser = async (ctx) => {
   try {
        const { id, nick, password, permission, oldPassword } = ctx.request.body;

        // 1. 校验必填参数：id
        if (!id) {
            ctx.status = 200;
            ctx.body = {
                code: 0,
                msg: '参数错误：缺少用户 ID',
                data: null,
            };
            return;
        }

        // 2. 初始化更新字段对象与参数数组
        const updateFields = []; // 要更新的字段，如 ['nick = ?', 'permission = ?']
        const updateValues = []; // 对应的值，如 [newNick, JSON.stringify(newPermission)]
        let needCheckOldPassword = false;

        // 3. 判断并处理每一个可能更新的字段
        if (nick !== undefined && nick !== null && nick !== '') {
            updateFields.push('nick = ?');
            updateValues.push(nick);
        }

        if (password !== undefined && password !== null && password !== '') {
            // 如果传了新密码，必须也传 oldPassword 用于校验
            if (!oldPassword || oldPassword === '') {
                ctx.status = 200;
                ctx.body = {
                    code: 0,
                    msg: '修改密码时必须提供原密码',
                    data: null,
                };
                return;
            }
            needCheckOldPassword = true;
            updateFields.push('password = ?');
            updateValues.push(password); // 先放进数组，后面再处理加密
        }

        if (permission !== undefined && permission !== null) {
            // 校验 permission 是否为数组（简单校验）
            if (!Array.isArray(permission)) {
                ctx.status = 200;
                ctx.body = {
                    code: 0,
                    msg: 'permission 必须是一个数组',
                    data: null,
                };
                return;
            }
            updateFields.push('permission = ?');
            updateValues.push(JSON.stringify(permission)); // 存为 JSON 字符串
        }

        // 4. 如果一个字段都不更新，直接返回
        if (updateFields.length === 0) {
            ctx.status = 200;
            ctx.body = {
                code: 0,
                msg: '没有提供任何需要更新的字段',
                data: null,
            };
            return;
        }

        // 5. 先查询当前用户信息（用于校验原密码）
        const selectSql = 'SELECT password FROM user WHERE id = ?';
        const [users] = await connection.execute(selectSql, [id]);

        if (users.length === 0) {
            ctx.status = 404;
            ctx.body = {
                code: 404,
                msg: '用户不存在',
                data: null,
            };
            return;
        }

        const currentUser = users[0];

        // 6. 如果要改密码，校验原密码是否正确
        if (needCheckOldPassword) {
            const isOldPasswordValid = await bcrypt.compare(oldPassword, currentUser.password);
            if (!isOldPasswordValid) {
                ctx.status = 200;
                ctx.body = {
                    code: 0,
                    msg: '原密码不正确',
                    data: null,
                };
                return;
            }
        }

        // 7. 如果有密码字段，需要对密码进行加密（即使在客户端加密了，也建议后端再加密一次）
        let finalUpdateValues = [...updateValues]; // 复制一份

        if (password !== undefined && password !== null && password !== '') {
            const saltRounds = 10;
            const hashedPassword = await bcrypt.hash(password, saltRounds);
            // 替换原来密码字段值为加密后的值
            finalUpdateValues[finalUpdateValues.indexOf(password)] = hashedPassword;
        }

        // 8. 拼接动态 SQL：UPDATE user SET field1=?, field2=? WHERE id=?
        const updateSql = `UPDATE user SET ${updateFields.join(', ')} WHERE id = ?`;
        const finalParams = [...finalUpdateValues, id];

        // 9. 执行更新
        await connection.execute(updateSql, finalParams);

        // 10. 返回成功信息
        ctx.status = 200;
        ctx.body = {
            code: 1,
            msg: '用户信息更新成功',
            data: {
                id,
                updatedFields: updateFields.map(f => f.replace(' = ?', '')), // 比如 ['nick', 'permission']
            },
        };

    } catch (error) {
        console.error('更新用户失败：', error);
        ctx.status = 500;
        ctx.body = {
            code: 500,
            msg: '服务器内部错误',
            data: null,
        };
    }
}





/**
 * 获取路由信息
 * @param {*} ctx 
 */
const getRouterInfo = async (ctx) => {
    try {
        const [rows] = await connection.query('SELECT * FROM router');
        ctx.status = 200;
        ctx.body = {
            code: 1,
            msg: '获取成功',
            data: rows,
        }
    } catch {
        ctx.status = 500;
        ctx.body = {
            code: 500,
            msg: '服务器错误',
            data: null,
        }
    }
}
module.exports = { login, register, getUserList,updateUser, getRouterInfo };
